home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 January / macformat-033.iso / mac / Shareware City / Developers / ABox.v1.8 / CPlus Files / ABSound.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  8.3 KB  |  314 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10. Product
  11.     About Box
  12.  
  13. FILE
  14.     ABSound.c
  15.  
  16. NAME
  17.     ABSound.c, part of the ABox project source code,
  18.     responsible for handling the AboutBox Sound class stuff.
  19.  
  20. DESCRIPTION
  21.     This file contains defines for the about box modules.
  22.     
  23. DEVELOPED BY
  24.     George (ty) Tempel                netromancr@aol.com
  25.     All code in this file, and its associated header file was
  26.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  27.     "FilterTop" application development, except where noted.
  28.  
  29. CARETAKER - George (ty) Tempel <netromancr@aol.com>
  30.      Please consult this person for any changes or suggestions to this file.
  31.  
  32. MODIFICATION HISTORY
  33.  
  34.     dd mmm yy    -    xxx    -    patchxx: description of patch
  35.     10 June 94    -    ty    -    Initial Version Created
  36.     20-july-94    -    ty    -    initial version released
  37.     28-july-94    -    ty    -    1.0.6 -- additions to play sound only if
  38.                                     the caller has set the ABox property
  39.                                     kABoxUseSoundMgr
  40.     12-jan-95    -    ty    -    1.1 -- edits to compensate for the differences 
  41.                                     between apple's universal headers releases...
  42.                                     i'll assume the newest stuff as the default
  43.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  44.                             release and the associated Universal Headers from Apple:
  45.                             most methods that returned references now have "Ref" at
  46.                             the end of their methods names to prevent possible collisions
  47.                             with datatypes and classes of the same name (older versions
  48.                             of the compiler didn't have a problem with this).
  49. */
  50.  
  51. /*===========================================================================*/
  52.  
  53. /*======= Segmentation directives ========*/
  54.  
  55. #ifdef USE_MANUAL_SEGMENTATION
  56. #pragma segment ty
  57. #endif
  58.  
  59. /*============ Header files ==============*/
  60.     
  61. #include     "ABSound.h"
  62. #include    "ABox.h"
  63.  
  64. /*=============== Globals ================*/
  65.  
  66. /*================ CODE ==================*/
  67.  
  68.  
  69. /*=============================== ABSound::ABSound ================================*/
  70. ABSound::ABSound(void)
  71. {
  72.     mSoundChannelDone = false;    //    used to indicate the channel should close down
  73.     mSoundChannelPtr = NULL;        //    the sound channel per-se
  74.     mSoundCallbackUPP = NULL;
  75.     //soundSignature = ++counter;    //    create a unique signature
  76.     mResType = kABSoundResource;
  77. } // end ABSound
  78.  
  79.  
  80.  
  81. /*=============================== ABSound::~ABSound ================================*/
  82. ABSound::~ABSound(void)
  83. {
  84.     Stop();
  85.     
  86. } // end ~ABSound
  87.  
  88.  
  89.  
  90.  
  91.  
  92. /*=============================== ABSound::Draw ================================*/
  93. OSErr    ABSound::Draw(WindowPtr window)
  94. {
  95.  
  96.     OSErr                error = noErr;
  97.     
  98.     //    begin here...
  99.     //
  100.  
  101.     error = ABObject::Draw(window);
  102.     
  103.     if (this->HasWindow())
  104.     {
  105.         //    1.0.6 ty--check to see if we're allowed to use the DragMgr
  106.         //
  107.         ABox *theABox = (ABox *)::GetWRefCon (this->OurWindowRef());
  108.         Boolean    useSnd = true;
  109.         
  110.         if (theABox)
  111.             error = theABox->GetProperty(kABoxUseSoundMgr, &useSnd, NULL);
  112.         
  113.         if (!useSnd)
  114.             return error;
  115.     }    // end if block
  116.     
  117.     this->SoundCallback() = NewSndCallBackProc (DoSnd_done);
  118.     error = ::SndNewChannel (&this->SoundChannelPointer(), 0, 0, this->SoundCallback());
  119.     
  120.     error = this->InitializeResource();
  121.  
  122.     //    1.1 edits to compensate for the differences between apple's universal
  123.     //    headers releases...i'll assume the newest stuff as the default
  124. #ifdef soundListRsrc
  125.     //    older version 1 universal headers
  126.     #define SndListHandle ResourceHandle
  127. #else
  128.     //    assume newer verions 2 universal headers
  129. #endif
  130.     //    1.1--edits for new universal headers
  131.     SndListHandle theSndListHandle = (SndListHandle)this->ResourceHandleRef();
  132.     
  133.     if (error) 
  134.     {
  135.         //    couldn't get a sound channel, so do it synchronously. Sigh.
  136.         this->SoundChannelPointer() = NULL;
  137.         this->SoundChannelDone() = false;
  138.  
  139.         error = ::SndPlay (NULL, theSndListHandle, false /* false = synchronous */);
  140.         if (error) 
  141.         {
  142.             //ABoxDebug(kABErrSndPlaySync, error);
  143.         } // end if block
  144.     } else {
  145.         
  146.         //    send the sound down the channel, followed by a callback command
  147.         //    to close the channel...see note below
  148.     
  149.         error = ::SndPlay (this->SoundChannelPointer(), theSndListHandle, true /* true = asynchronous*/);
  150.         if (error) 
  151.         {
  152.             //    problems playing async, so trash the channel and do it sync
  153.             //
  154.             this->SoundChannelDone() = true;
  155.             this->Stop();
  156.             error = ::SndPlay (NULL, theSndListHandle, false /* false = synchronous */);
  157.             if (error) 
  158.             {
  159.                 //ABoxDebug(kABErrSndPlaySync, error);
  160.             } // end if block
  161.         }    else {
  162.             //    no problems, play it async...
  163.             //
  164.             
  165.             this->SoundChannelDone() = false;
  166.             
  167.         }    //    end if else block...
  168.         
  169.     } // end if (error) block on SndNewChannel status
  170.     
  171.     //    now return to the caller...
  172.     
  173.     return error;
  174. } // end Draw
  175.  
  176.  
  177.  
  178.  
  179.  
  180. /*=============================== ABSound::Update ================================*/
  181. OSErr    ABSound::Update(WindowPtr window)
  182. {
  183.     
  184.     //    begin here...
  185.     //
  186.     
  187.     this->OurWindowRef() = window;
  188.     return noErr;
  189. } // end Update
  190.  
  191.  
  192.  
  193.  
  194.  
  195. /*=============================== DoSnd_done ===============================*/
  196. //
  197. //    a function to close down a sound channel.
  198. //
  199. //    this function is called via an interrupt by the sound manager if
  200. //    we queued a sound into a channel.
  201. //
  202. //    is called by:
  203. //        the asynchronous portion of the sound manager
  204. //
  205. pascal void    ABSound::DoSnd_done (SndChannelPtr /*channel*/, SndCommand *command)
  206. {
  207.     OSErr    error = noErr;
  208.     
  209.     long    otherA5;
  210.     
  211.     // Look for our "callback signature" in the sound command.
  212.     // from: SoundHelper.c - the Asynchronous Sound Helper,
  213.     //    Apple DTS, by Bryan K. Ressler (Beaker), 2/4/92
  214.     //
  215.     //    This routine first looks for our "completion signature."  This is how we know
  216.     //    that the callback really means the sound has completed.  There is a bug in the
  217.     //    Sound Manager that may cause callbacks that weren't specifically requested, and
  218.     //    this constant allows us to distinguish our "real" callback from one that is a
  219.     //    result of that bug.  If the callback is hip the channel can be freed.
  220.     //
  221.  
  222.     if (!command)                            //    1.0a5 ty...added check just to be sure
  223.         return;
  224.         
  225.     if (command->param1 == kABSoundSignature) 
  226.     {
  227.         //    close down the sound channel...
  228.         //
  229.         otherA5 = ::SetA5(command->param2);    // Set up our A5
  230.         //
  231.         //    NEVER EVER EVER play with memory here...you can't guarantee where it
  232.         //    really is because we've been called at interrupt time! Instead
  233.         //    set a global flag that someone else can see and act upon! I learned
  234.         //    this the _hard_ way...
  235.         //
  236.         //gSoundChannelDone = true;
  237.         ::SetA5(otherA5);                        // Retore old A5
  238.  
  239.     }    //    end if block...
  240.  
  241.     return;
  242. }    //    end of function DoSnd_done()
  243.  
  244.  
  245.  
  246.  
  247.  
  248. /*=============================== ABSound::Stop ================================*/
  249. OSErr    ABSound::Stop(void)
  250. {
  251.     OSErr        error = noErr;
  252.     Boolean        quietNow = true;
  253.     SndCommand    command;                    //    1.0a3 patch ty ... moved to this block from below
  254.     
  255.     if (this->DoesntHaveSoundChannelPointer()) 
  256.     {
  257.         //    false alarm...
  258.         return error;
  259.     
  260.     } else {
  261.         command.cmd = quietCmd;                //    1.0a4p2 ty...added a quietCmd here
  262.         command.param1 = kABnoSoundParam1;
  263.         command.param2 = kABnoSoundParam2;
  264.         error = ::SndDoImmediate (this->SoundChannelPointer(), &command); 
  265.  
  266.         command.cmd = flushCmd;
  267.         command.param1 = kABnoSoundParam1;
  268.         command.param2 = kABnoSoundParam2;
  269.         error = ::SndDoImmediate (this->SoundChannelPointer(), &command); 
  270.  
  271.         command.cmd = quietCmd;
  272.         command.param1 = kABnoSoundParam1;
  273.         command.param2 = kABnoSoundParam2;
  274.         error = ::SndDoImmediate (this->SoundChannelPointer(), &command); 
  275.  
  276.         //    a slight delay has been added here before we go on
  277.         //    to kill the sound channel. This seems to stop the
  278.         //    chirp or squeak that sometimes occurs
  279.         command.cmd = waitCmd;
  280.         command.param1 = kABsoundDelayHalfMilliseconds;
  281.         command.param2 = kABnoSoundParam2;
  282.         error = ::SndDoImmediate (this->SoundChannelPointer(), &command); 
  283.  
  284.         this->SoundChannelDone() = true;
  285.     }    //    end if block
  286.     
  287.     if (this->IsSoundChannelDone() && this->HasSoundChannelPointer()) 
  288.     {
  289.         //ABoxDebugDelete ();
  290.         error = ::SndDisposeChannel (this->SoundChannelPointer(), quietNow);
  291.         this->SoundChannelPointer() = NULL;
  292.         this->SoundChannelDone() = false;
  293.     }    //    end if block to wipe out the sound channel.
  294.  
  295.     if (this->HasSoundCallback()) 
  296.     {
  297.         //ABoxDebugDelete();
  298.         DisposeRoutineDescriptor (this->SoundCallback());
  299.     }    //    end if block
  300.     
  301.     
  302.     error = ABResource::Stop();
  303.     
  304.     return error;
  305.  
  306. } // end Stop
  307.  
  308.  
  309.  
  310.  
  311.  
  312. //    end of file
  313.  
  314.